import * as _ from "lodash"
import { snakeCase } from "../case"
import httpClient from "../httpclient"

export enum Gender {
  Male = "male",
  Female = "female",
  Unknown = "unknown"
}

export class User {
  public id: string
  public username: string
  public nickname: string
  public phone: string
  public avatar: string
  private country_code: string

  public get countryCode() {
    return this.country_code
  }

  public set countryCode(countryCode) {
    this.country_code = countryCode
  }
}

export enum UserRegistrationMode {
  Email = "email",
  PhoneCaptcha = "phone_captcha"
}

export class UserRegistration {
  public static Mode = UserRegistrationMode
  public mode: UserRegistrationMode
  public username: string
  public password: string
  public nickname: string
  public countryCode: string
  public phone: string
  public email: string
  public captchaToken?: string
  public captchaCode?: string
}

interface UserSearch {
  username?: string
  countryCode?: string
  phone?: string
}

enum UserRetakeMode {
  UsernamePassword = "username_password",
  EmailPassword = "email_password",
  PhonePassword = "phone_password",
  PhoneCaptcha = "phone_captcha"
}

export class UserRetake {
  public static Mode = UserRetakeMode
  public mode: UserRetakeMode
  public tenantId?: string
  public originalPassword?: string
  public password?: string
  public username?: string
  public countryCode?: string
  public phone?: string
  public email?: string
  public captchaToken?: string
  public captchaCode?: string
}

export class UserServiceV1 {

  public static createUser(registration: UserRegistration): Promise<User> {
    return httpClient.post(`/v1/users`, snakeCase(registration))
      .then(({ data }) => _.assign(new User(), data))
  }

  public static retakeUser(retake: UserRetake): Promise<User> {
    return httpClient.patch(`/v1/users/retake`, snakeCase(retake))
      .then(({ data }) => _.assign(new User(), data))
  }

  public static findUser(search: UserSearch): Promise<User> {
    return httpClient
      .get(`/v1/users/find`, {
        params: snakeCase(search),
      })
      .then(({ data }) => _.isNull(data) || _.isUndefined(data) ? undefined : _.assign(new User(), data))
  }

  public static getUser(userId: string): Promise<User> {
    return httpClient.get(`/v1/users/${userId}`)
      .then(({ data }) => _.assign(new User(), data))
  }

  public static getCurrentUser(): Promise<User> {
    return httpClient.get(`/v1/users/current`)
      .then(({ data }) => _.assign(new User(), data))
  }
}
